<?php
namespace app\admin\controller;
use think\Controller;
class Common extends Controller
{

    public function _initialize(){
        if (!session('?admin_auth')) {
            session('go',url('admin/index/index'));
            $this -> redirect('admin/auth/login');
        }
        \think\Hook::listen('admin_init');
        if (request() -> isPost()) {
            if (function_exists('segment')) {
                \think\Hook::add('app_end','app\\senior\\behavior\\Clearcache');
            }else{
                \think\Hook::add('app_end','app\\admin\\behavior\\Clearcache');
            }
            // 开启日志记录
            if (\ebcms\Config::get('system.oplog_on')) {
                \think\Hook::add('app_end','app\\admin\\behavior\\Oplog');
            }
        }
        \think\Config::set('app_trace',false);
    }

    // 获取数据
    protected function modeldata($p = []){
        $request = request();
        if (!$p) {
            $p = $request -> param();
        }
        if (!isset($p['model'])) {
            $p['model'] = $request->controller();
        }
        if (!isset($p['where'])) {
            $p['where'] = [];
        }else{
            foreach ($p['where'] as &$a) {
                foreach ($a as &$b) {
                    $b = is_string($b)?trim($b):$b;
                }
            }
        }
        if (!isset($p['with'])) {
            $p['with'] = '';
        }
        $m = \think\Loader::model($p['model']);
        // 获取排序
        if (input('order/a')) {
            $m -> order(input('order/a'));
        }
        $result = [];
        // 获取内容
        $rows = input('rows',0,'intval')?:1000;
        $result = $m::with($p['with']) -> where($p['where']) -> paginate($rows);
        $result = $result -> toArray();
        $result['rows'] = $result['data'];
        unset($result['data']);
        
        $this -> success('获取成功！','',$result);
    }

    protected function fetchform($data=array(),$config=array()){
        $form = $this -> getform($data,$config);
        $this -> assign($form);
        $this -> assign('_data',$data);
        $this -> success('','',$this -> fetch('admin@common/form'));
    }

    // 返回表单
    protected function getform($data=array(),$config=array()){

        $res = [];

        $config['formname'] = isset($config['formname'])?$config['formname']:request() -> module().'_'.request() -> controller().'_'.request() -> action();
        $config['action'] = isset($config['action'])?$config['action']:request() -> module().'/'.request() -> controller().'/'.request() -> action();
        $_where = [
            'status' => array('eq',1),
            'name' => array('eq',$config['formname']),
            ];
        if ($form = \think\Db::name('form') -> where($_where) -> find()) {
            $_where = [
                'status' => array('eq',1),
                'category_id' => array('eq',$form['id']),
                ];
            $_fields = \app\admin\model\Formfield::where($_where) -> field(true) -> order('sort desc,id asc') -> select();
            $groups = [];
            foreach ($_fields as $key => $value) {
                $tmp = [];
                // 字段配置
                $tmp['id'] = $value['id'];
                $tmp['config'] = $value['config'];
                $tmp['title'] = $value['title'];
                $tmp['remark'] = $value['remark'];
                $tmp['type'] = substr($value['type'],5);
                // 字段名称
                if ($value['subtable'] && $value['extfield']) {
                    $tmp['field'] = $value['subtable'].'['.$value['extfield'].']'.'['.$value['name'].']';
                }elseif ($value['extfield']) {
                    $tmp['field'] = $value['extfield'].'['.$value['name'].']';
                }elseif ($value['subtable']) {
                    $tmp['field'] = $value['subtable'].'['.$value['name'].']';
                }else{
                    $tmp['field'] = $value['name'];
                }
                // 字段值
                switch ($value['defaultvaluetype']) {
                    case '0':
                        $tmp['value'] = $value['defaultvalue'];
                        break;

                    case '1':
                        $tmp['value'] = input($value['defaultvalue']);
                        break;

                    case '2':
                        $tmp['value']  = config($value['defaultvalue']);
                        break;

                    case '3':
                        if ($value['subtable'] && $value['extfield']) {
                            $_value = $data[$value['subtable']][$value['extfield']];
                        }elseif ($value['extfield']) {
                            $_value = $data[$value['extfield']];
                        }elseif ($value['subtable']) {
                            $_value = $data[$value['subtable']];
                        }else{
                            $_value = $data;
                        }
                        $tmp['value'] = $this -> get_point_value($_value,$value['defaultvalue']);
                        break;
                    
                    default:
                        $tmp['value'] = $value['defaultvalue'];
                        break;
                }
                $groups[$value['group']][$value['id']] = $tmp;
            }
            $form['action'] = \think\Url::build($config['action']);
            $form['formtime'] = time();
            $res['_form'] = $form;
            $res['_groups'] = $groups;

            // 扩展字段
            if (isset($config['ext_id']) && $config['ext_id']) {
                $_where = array(
                    'category_id' => array('eq',$config['ext_id']),
                    'status' => array('eq',1),
                    );
                if ($extfields = \app\admin\model\Extendfield::where($_where) -> field(true) -> order('sort desc,id asc') -> select()) {
                    $extgroups = [];
                    foreach ($extfields as $key => $extfield) {
                        $tmp = [];
                        // 字段配置
                        $tmp['id'] = $extfield['id'];
                        $tmp['config'] = $extfield['config'];
                        $tmp['title'] = $extfield['title'];
                        $tmp['remark'] = $extfield['remark'];
                        $tmp['type'] = substr($extfield['type'],5);
                        // 字段名称
                        if (isset($config['ext_table']) && $config['ext_table']) {
                            $tmp['field'] = $config['ext_table'].'[ext]'.'['.$extfield['name'].']';
                        }else{
                            $tmp['field'] = 'ext['.$extfield['name'].']';
                        }
                        // 字段值
                        $tmp['value'] = '';
                        if ($data) {
                            if (isset($config['ext_table']) && $config['ext_table']) {
                                $_value = $data[$config['ext_table']]['ext'];
                                $tmp['value'] = isset($_value[$extfield['name']])?$_value[$extfield['name']]:$extfield['value'];
                            }elseif(isset($data['ext'])){
                                $_value = $data['ext'];
                                $tmp['value'] = isset($_value[$extfield['name']])?$_value[$extfield['name']]:$extfield['value'];
                            }
                        }
                        $extgroups[$extfield['group']][$extfield['id']] = $tmp;
                    }
                    $res['_extgroups'] = $extgroups;
                }
            }elseif (isset($config['single_ext_id']) && $config['single_ext_id']) {
                $_where = array(
                    'single_id' => array('eq',$config['single_ext_id']),
                    'status' => array('eq',1),
                    );
                if ($extfields = \app\admin\model\Extendfield::where($_where) -> field(true) -> order('sort desc,id asc') -> select()) {
                    $extgroups = [];
                    foreach ($extfields as $key => $extfield) {
                        $tmp = [];
                        // 字段配置
                        $tmp['id'] = $extfield['id'];
                        $tmp['config'] = $extfield['config'];
                        $tmp['title'] = $extfield['title'];
                        $tmp['remark'] = $extfield['remark'];
                        $tmp['type'] = substr($extfield['type'],5);
                        // 字段名称
                        if (isset($config['ext_table']) && $config['ext_table']) {
                            $tmp['field'] = $config['ext_table'].'[ext]'.'['.$extfield['name'].']';
                        }else{
                            $tmp['field'] = 'ext['.$extfield['name'].']';
                        }
                        // 字段值
                        $tmp['value'] = '';
                        if ($data) {
                            if (isset($config['ext_table']) && $config['ext_table']) {
                                $_value = $data[$config['ext_table']]['ext'];
                                $tmp['value'] = isset($_value[$extfield['name']])?$_value[$extfield['name']]:$extfield['value'];
                            }elseif(isset($data['ext'])){
                                $_value = $data['ext'];
                                $tmp['value'] = isset($_value[$extfield['name']])?$_value[$extfield['name']]:$extfield['value'];
                            }
                        }
                        $extgroups[$extfield['group']][$extfield['id']] = $tmp;
                    }
                    $res['_extgroups'] = $extgroups;
                }
            }

            if (input('__modal') == 1) {
                $res['__modal'] = 1;
            }else{
                $res['__modal'] = 0;
            }
            $res['namespace'] = ns();
            return $res;
        }else{
            $this -> error('表单配置错误！');
        }
    }

    protected function ebadd($config=[],$back=false){
        if (request() -> isGet()) {
            $this -> fetchform();
        }else if (request() -> isPost()) {
            $config['model'] = isset($config['model'])?$config['model']:get_model_controller(request() -> controller());
            $config['module'] = isset($config['module'])?$config['module']:request() -> module();
            $m = \think\Loader::model($config['module'].'/'.$config['model']);
            $input = input();
            $config['allowfield'] = isset($config['allowfield'])?$config['allowfield']:true;
            $config['validate'] = isset($config['validate_scene'])?$config['model'].'.'.$config['validate_scene']:$config['model'];
            if (false !== $id = $m -> allowField($config['allowfield']) -> validate($config['validate']) -> save($input)) {
                if (isset($config['relation']) && $config['relation']) {
                    foreach ($config['relation'] as $relation => $opt) {
                        switch ($opt['type']) {
                            case 'hasone':
                                $m -> $relation() -> save($input[$relation]);
                                break;
                            case 'hasmany':
                                $m -> $relation() -> saveAll($input[$relation]);
                                break;
                            case 'manytomany':
                                $m -> $relation() -> saveAll($input[$relation]);
                                break;
                        }
                    }
                }
                if ($back == true) {
                    return $id;
                }else{
                    $this -> success('新增成功！','',['id'=>$id]);
                }
            }else{
                $this -> error($m -> getError());
            }
        }
    }

    protected function ebedit($config=[],$back=false){
        if (request() -> isGet()) {
            $id = isset($config['id'])?$config['id']:input('id');
            $config['model'] = isset($config['model'])?$config['model']:get_model_controller(request() -> controller());
            $config['module'] = isset($config['module'])?$config['module']:request() -> module();
            $m = \think\Loader::model($config['module'].'/'.$config['model']);
            $this -> fetchform($m -> get($id));
        }else if (request() -> isPost()) {
            $id = isset($config['id'])?$config['id']:input('id');
            $config['model'] = isset($config['model'])?$config['model']:get_model_controller(request() -> controller());
            $config['module'] = isset($config['module'])?$config['module']:request() -> module();
            $m = \think\Loader::model($config['module'].'/'.$config['model']);
            $data = $m -> get($id);
            if (true != session('super_admin') && $data['locked']) {
                $this -> error('锁定的数据可解锁后修改！');
            }
            $input = input();
            $config['allowfield'] = isset($config['allowfield'])?$config['allowfield']:true;
            $config['validate'] = isset($config['validate_scene'])?$config['model'].'.'.$config['validate_scene']:$config['model'];
            if (false !== $m -> allowField($config['allowfield']) -> validate($config['validate']) -> save($input,['id'=>$id])) {
                if (isset($config['relation']) && $config['relation']) {
                    foreach ($config['relation'] as $relation => $opt) {
                        switch ($opt['type']) {
                            case 'hasone':
                                $opt['validate'] = isset($opt['validate_scene'])?$relation.'.'.$opt['validate_scene']:$relation;
                                $opt['allowfield'] = isset($opt['allowfield'])?$opt['allowfield']:true;
                                if (false === $m -> $relation -> allowField($opt['allowfield']) -> validate($opt['validate']) -> save($input[$relation])) {
                                    $this -> error($m -> $relation -> getError());
                                }
                                break;
                            case 'hasmany':
                                $m -> $relation() -> delete();
                                $m -> $relation() -> saveAll($input[$relation]);
                                break;
                            case 'manytomany':
                                $m -> $relation() -> detach(true);
                                $m -> $relation() -> saveAll($input[$relation]);
                                break;
                        }
                    }
                }
                if ($back == true) {
                    return true;
                }else{
                    return $this -> success('修改成功！');
                }
            }else{
                $this -> error($m -> getError());
            }
        }
    }

    protected function ebdelete($config=[],$data=[]){
        if (false !== $res = $this -> _ebdelete($config,$data)) {
            $this -> success('删除成功！','',$res);
        }else{
            $this -> error('删除失败！');
        }
    }

    // 删除
    protected function _ebdelete($config = [],$data=[]){

        if (isset($data['ids'])) {
            $ids = (array)$data['ids'];
        }elseif ($ids = input('ids')) {
            $ids = explode(',', $ids);
        }

        if ($ids) {
            $config['model'] = isset($config['model'])?$config['model']:get_model_controller(request() -> controller());
            $config['module'] = isset($config['module'])?$config['module']:request() -> module();
            $m = \think\Loader::model($config['module'].'/'.$config['model']);
            $map['id'] = array('in',$ids);
            // 排除锁定项 
            if (!session('super_admin') && !isset($config['unlock'])) {
                $map['locked'] = array('eq',0);
            }
            if (isset($config['relation']) && $config['relation']) {
                $lists = $m -> where($map) -> select();
                if ($lists) {
                    foreach ($lists as $vo) {
                        foreach ($config['relation'] as $relation => $opt) {
                            switch ($opt['type']) {
                                case 'hasone':
                                    if (isset($opt['sub'])) {
                                        $this -> _ebdelete($opt['sub'],['ids'=>$vo['id']]);
                                    }
                                    $vo -> $relation -> delete();
                                    break;
                                case 'hasmany':
                                    if (isset($opt['sub'])) {
                                        $rel = $vo -> $relation;
                                        $subids = [];
                                        foreach ($rel as $re) {
                                            $subids[] = $re['id'];
                                        }
                                        if ($subids) {
                                            $this -> _ebdelete($opt['sub'],['ids'=>$subids]);
                                        }
                                    }
                                    $vo -> $relation() -> delete();
                                    break;
                                case 'manytomany':
                                    $vo -> $relation() -> detach(true);
                                    break;
                            }
                        }
                        $vo -> delete();
                    }
                }
            }else{
                $lists = $m -> where($map) -> select();
                $m -> where($map) -> delete();
            }
            $res = [];
            foreach ($lists as $list) {
                $res[] = $list -> toArray();
            }
            return $res;
        }else{
            return false;
        }
    }

    // 审核
    protected function ebstatus($config=[]){

        if (isset($config['ids'])) {
            $ids = (array)$config['ids'];
        }elseif ($ids = input('ids')) {
            $ids = explode(',', $ids);
        }
        if (empty($ids)) {
            $this -> error('请选择要 操作 的数据！');
        }

        if (isset($config['value'])) {
            $value = (int)$config['value'];
        }else{
            $value = input('value',0,'intval')?1:0;
        }

        $this -> ebfield($ids,'status',$value,$config);

    }

    // 排序 推荐
    protected function ebsort($config=[]){

        if (isset($config['ids'])) {
            $ids = (array)$config['ids'];
        }elseif ($ids = input('ids')) {
            $ids = explode(',', $ids);
        }
        if (empty($ids)) {
            $this -> error('请选择要 操作 的数据！');
        }

        if (isset($config['value'])) {
            $value = (int)$config['value'];
        }else{
            $value = input('value',0,'intval');
        }

        $this -> ebfield($ids,'sort',$value,$config);

    }

    protected function ebfield($ids,$field,$value,$config=[]){

        $config['model'] = isset($config['model'])?$config['model']:get_model_controller(request() -> controller());
        $config['module'] = isset($config['module'])?$config['module']:request() -> module();
        $m = \think\Loader::model($config['module'].'/'.$config['model']);

        $where = [];
        // 排除锁定项
        if (true != session('super_admin')) {
            $where['locked'] = array('eq',0);
        }
        $where['id'] = array('in',$ids);

        $num = $m -> where($where) -> setField($field,$value);
        if (false === $num) {
            $this -> error('操作失败！');
        }elseif (is_numeric($num)) {
            $this -> success('操作成功！');
        }
    }

    // 锁定
    protected function eblock($config=[]){

        if (isset($config['ids'])) {
            $ids = (array)$config['ids'];
        }elseif ($ids = input('ids')) {
            $ids = explode(',', $ids);
        }
        if (empty($ids)) {
            $this -> error('请选择要 操作 的数据！');
        }

        if (isset($config['value'])) {
            $value = (int)$config['value'];
        }else{
            $value = input('value')?1:0;
        }

        $config['model'] = isset($config['model'])?$config['model']:get_model_controller(request() -> controller());
        $config['module'] = isset($config['module'])?$config['module']:request() -> module();
        $m = \think\Loader::model($config['module'].'/'.$config['model']);

        $where = [];
        if (is_array($ids)) {
            $where['id'] = array('in',$ids);
        } elseif (is_numeric($ids)) {
            $where['id'] = array('eq',$ids);
        }

        $num = $m -> where($where) -> setField('locked',$value);
        if (false === $num) {
            $this -> error('操作失败！');
        }elseif (is_numeric($num)) {
            $this -> success('操作成功！');
        }
    }

    private function get_point_value($data=[],$str){
        $pos = strpos($str, '.');
        if (false === $pos) {
            return isset($data[$str])?$data[$str]:false;
        }else{
            $key = mb_substr($str, 0,$pos);
            if (isset($data[$key])) {
                return $this -> get_point_value($data[$key],mb_substr($str, $pos+1));
            }else{
                return false;
            }
        }
    }

    // 空控制器
    public function _empty()
    {
        $action = request() -> action();
        switch ($action) {
            case 'add':
                if (request()->isGet()) {
                    $this -> fetchform();
                }elseif (request()->isPost()) {
                    $this -> ebadd();
                }
                break;

            case 'edit':
                if (request()->isGet()) {
                    $data = \think\Db::name(request() -> controller()) -> find(input('id'));
                    $this -> fetchform($data);
                }elseif (request()->isPost()) {
                    $this -> ebedit();
                }
                break;
            
            // 排序
            case 'resort':
                if (request()->isGet()) {
                    // $this -> fetchform();
                }elseif (request()->isPost()) {
                    $this -> ebsort();
                }
                break;

            // 删除
            case 'delete':
                $this -> ebdelete();
                break;

            // 审核
            case 'status':
                $this -> ebstatus();
                break;

            // 锁定
            case 'lock':
                $this -> eblock();
                break;

            default:
                $this -> error('错误请求！');
                break;
        }
    }

}